package com.cloudptt.api.product.operator;


import com.cloudptt.api.comm.CauseCont;
import com.cloudptt.api.pjsua2.MyCall;
import com.cloudptt.api.pjsua2.service.PjsuaService;
import com.cloudptt.api.product.func.SipOperator;
import com.cloudptt.api.product.log.Log;

import android.content.Context;
import android.os.RemoteException;
import android.view.Surface;

import java.util.List;

public class CallOperator extends SipOperator
{
	private final static String THIS_FILE = "CallOperator";
	public final static int Audio_Dir_SendOnly = 3;
	public final static int Audio_Dir_RecvOnly = 5;
	public final static int Audio_Dir_Mask = 0xffff;

	public final static int Video_Dir_SendOnly = 0x30000;
	public final static int Video_Dir_RecvOnly = 0x50000;
	public final static int Video_Dir_Mask = 0xffff0000;

//	private boolean isAuthorize_Ptt = false;
//	private boolean isAuthorize_Video = false;

//	protected SipCallSession curCallSession = null;


	public CallOperator(Context ctx)
	{
		super(ctx);
		Log.d(THIS_FILE, "CallOperator");
	}

	public int makeCall(int callType, String groupNum, String called)
	{
		Log.d(THIS_FILE, "makeCall groupNum = " + groupNum + " called = " + called);
		int result = checkFirst();
		if(CauseCont.OperateCheck_Suc != result)
		{
			return result;
		}
//		if(!isAuthorize_Ptt)
//		{
//			return CauseCont.OperateErr_NoAuthorize_Ptt;
//		}
		
		
//		Bundle b = new Bundle();
//		b.putBoolean(SipCallSession.OPT_CALL_VIDEO, false );

		try 
		{
			result = service.makeCallWithOptions(groupNum,called, callType, false);
			if(CauseCont.OperateCheck_Suc == result)
			{
//				setSpeakerphoneOn(CallAttr.CallType_Group);
			}
			return result;
		} 
		catch (Exception e) 
		{
			e.printStackTrace();
			return CauseCont.OperateCheck_Sys_OperateException;
		}
	}
	
	public int makeSingleCall(int type,String num,String called,boolean isHaveVideo) 
	{
		Log.d(THIS_FILE, "makeSingleCall num = " + num + " called = " + called + " isHaveVideo = " + isHaveVideo);
		int result = checkFirst();
		if(CauseCont.OperateCheck_Suc != result)
		{
			return result;
		}

		try 
		{
			result = service.makeCallWithOptions(num,called, type, isHaveVideo);
			if(CauseCont.OperateCheck_Suc == result)
			{
//				setSpeakerphoneOn(CallAttr.CallType_Group);
			}
			return result;
		} 
		catch (Exception e) 
		{
			e.printStackTrace();
			return CauseCont.OperateCheck_Sys_OperateException;
		}
	}

	public int hangupCall(String callIdStr,int statusCode)
	{
		Log.d(THIS_FILE, "hangupCall callIdStr is "+ callIdStr + " statusCode = " + statusCode);

		if(callIdStr == null
				|| callIdStr.equals(MyCall.DEF_CALL_ID_STR))
		{
			return CauseCont.OperateCheck_Sys_OperateException;
		}
		
		try
		{
			return service.hangup(callIdStr, statusCode);
		}
		catch(Exception e)
		{
			e.printStackTrace();
			return CauseCont.OperateCheck_Sys_OperateException;
		}
	}

	public int answerCall(String callIdStr,int callType,String called,String callee,boolean hasVideo)
	{
		Log.d(THIS_FILE, "answerCall callIdStr = "+ callIdStr  + " callType = "+ callType + " called = "+ called + " callee = "+ callee);
		if(callIdStr == null
				|| callIdStr.equals(MyCall.DEF_CALL_ID_STR))
		{
			return CauseCont.OperateCheck_Sys_OperateException;
		}
		
		int result = checkFirst();
		if(CauseCont.OperateCheck_Suc != result)
		{
			return result;
		}
		
//		int accId = 0;
//		int callId = 0;
//		int mcType = SipCallSession.McType_PTT;
////		String extStr = "";
//		if(curCallSession != null)
//		{
//			accId = (int)curCallSession.getAccId();
//			callId = curCallSession.getCallId();
//			mcType = curCallSession.getMcType();
////			extStr = curCallSession.getReqExtStr();
//		}

		try
		{
			result = service.answer(callIdStr, 200, callType,called,hasVideo);
			if(CauseCont.OperateCheck_Suc == result)
			{
//				setSpeakerphoneOn(callType);
			}
			return result;
		}
		catch(Exception e)
		{
			e.printStackTrace();
			return CauseCont.OperateCheck_Sys_OperateException;
		}
	}

//	public SurfaceView createCallSurfaceView(Context ctx,boolean isLocal)
//	{
//		if(isLocal)
//		{
//			return ViERenderer.CreateLocalRenderer(ctx);
//		}
//		else
//		{
//			return ViERenderer.CreateRenderer(ctx, true);
//		}
//	}
	
//	public int setVideoWindow(int callId,SurfaceView view,boolean isLocal)
//	{
//		Log.d(THIS_FILE, "answerCall callId = "+ callId + " isLocal = "+ isLocal);
//		if(callId < 0
//				|| callId > 255)
//		{
//			return CauseCont.OperateCheck_Sys_OperateException;
//		}
//
//		int result = checkFirst();
//		if(CauseCont.OperateCheck_Suc != result)
//		{
//			return result;
//		}
//
//		try
//		{
//			SipService.setVideoWindow(callId, view, isLocal);
//			return result;
//		}
//		catch(Exception e)
//		{
//			e.printStackTrace();
//			return CauseCont.OperateCheck_Sys_OperateException;
//		}
//	}

	public int requestSpeaking(String callIdStr,int level,String gNum,String uName)
	{
		Log.d(THIS_FILE, "requestSpeaking callIdStr = " + callIdStr + " gNum = " + gNum + " uName = " + uName);

		if(callIdStr == null
				|| callIdStr.equals(MyCall.DEF_CALL_ID_STR))
		{
			return CauseCont.OperateCheck_Sys_OperateException;
		}
		
		int result = checkFirst();
		if(CauseCont.OperateCheck_Suc != result)
		{
			return result;
		}

		try
		{
			return service.floorRequest(callIdStr,level,gNum,uName);
		}
		catch(Exception e)
		{
			e.printStackTrace();
			return CauseCont.OperateCheck_Sys_OperateException;
		}
	}
	public int releaseSpeaking(String callIdStr,int level,String gNum,String uName)
	{
		Log.d(THIS_FILE, "releaseSpeaking callIdStr = " + callIdStr + " gNum = " + gNum + " uName = " + uName);
		if(callIdStr == null
				|| callIdStr.equals(MyCall.DEF_CALL_ID_STR))
		{
			return CauseCont.OperateCheck_Sys_OperateException;
		}
		
		int result = checkFirst();
		if(CauseCont.OperateCheck_Suc != result)
		{
			return result;
		}

		try
		{
			return service.floorRelease(callIdStr,level,gNum,uName);
		}
		catch(Exception e)
		{
			e.printStackTrace();
			return CauseCont.OperateCheck_Sys_OperateException;
		}
	}
	
	public int requestTrans(String callIdStr)
	{
		Log.d(THIS_FILE, "requestTrans callIdStr = " + callIdStr);
		if(callIdStr == null
				|| callIdStr.equals(MyCall.DEF_CALL_ID_STR))
		{
			return CauseCont.OperateCheck_Sys_OperateException;
		}
		
		int result = checkFirst();
		if(CauseCont.OperateCheck_Suc != result)
		{
			return result;
		}

		try
		{
			return service.requestTrans(callIdStr);
		}
		catch(Exception e)
		{ 
			e.printStackTrace();
			return CauseCont.OperateCheck_Sys_OperateException;
		}
	}
	
	public int releaseTrans(String callIdStr)
	{
		Log.d(THIS_FILE, "releaseTrans callIdStr = " + callIdStr);
		if(callIdStr == null
				|| callIdStr.equals(MyCall.DEF_CALL_ID_STR))
		{
			return CauseCont.OperateCheck_Sys_OperateException;
		}
		
		int result = checkFirst();
		if(CauseCont.OperateCheck_Suc != result)
		{
			return result;
		}

		try
		{
			return service.releaseTrans(callIdStr);
		}
		catch(Exception e)
		{ 
			e.printStackTrace();
			return CauseCont.OperateCheck_Sys_OperateException;
		}
	}
	public int negotiateRtpRtcpChannel(String callIdStr,String gNum,String uNum)
	{
		Log.d(THIS_FILE, "negotiateRtpRtcpChannel callIdStr = " + callIdStr  + " gNum = " + gNum + " uNum = " + uNum);
		if(callIdStr == null
				|| callIdStr.equals(MyCall.DEF_CALL_ID_STR))
		{
			return CauseCont.OperateCheck_Sys_OperateException;
		}

		int result = checkFirst();
		if(CauseCont.OperateCheck_Suc != result)
		{
			return result;
		}

		try
		{
			return service.negotiateGroupRtpRtcpChannel(callIdStr,gNum,uNum);
		}
		catch(Exception e)
		{
			e.printStackTrace();
			return CauseCont.OperateCheck_Sys_OperateException;
		}
	}

	public int negotiateRtcpChannel(String callIdStr,String gNum,String uNum)
	{
		Log.d(THIS_FILE, "negotiateRtcpChannel callIdStr = " + callIdStr + " gNum = " + gNum + " uNum = " + uNum);
		if(callIdStr == null
				|| callIdStr.equals(MyCall.DEF_CALL_ID_STR))
		{
			return CauseCont.OperateCheck_Sys_OperateException;
		}

		int result = checkFirst();
		if(CauseCont.OperateCheck_Suc != result)
		{
			return result;
		}

		try
		{
			return service.negotiateGroupRtcpChannel(callIdStr,gNum,uNum);
		}
		catch(Exception e)
		{
			e.printStackTrace();
			return CauseCont.OperateCheck_Sys_OperateException;
		}
	}

	public int negotiateRtpChannel(String callIdStr)
	{
		Log.d(THIS_FILE, "negotiateRtpChannel callIdStr = " + callIdStr);
		if(callIdStr == null
				|| callIdStr.equals(MyCall.DEF_CALL_ID_STR))
		{
			return CauseCont.OperateCheck_Sys_OperateException;
		}
		
		int result = checkFirst();
		if(CauseCont.OperateCheck_Suc != result)
		{
			return result;
		}

		try
		{
			return service.negotiateRtpChannel(callIdStr);
		}
		catch(Exception e)
		{ 
			e.printStackTrace();
			return CauseCont.OperateCheck_Sys_OperateException;
		}
	}
	
	public int negotiateVideoChannel(String callIdStr)
	{
		Log.d(THIS_FILE, "negotiateVideoChannel callIdStr = " + callIdStr);
		if(callIdStr == null
				|| callIdStr.equals(MyCall.DEF_CALL_ID_STR))
		{
			return CauseCont.OperateCheck_Sys_OperateException;
		}
		
		int result = checkFirst();
		if(CauseCont.OperateCheck_Suc != result)
		{
			return result;
		}

		try
		{
			return service.negotiateVideoChannel(callIdStr);
		}
		catch(Exception e)
		{ 
			e.printStackTrace();
			return CauseCont.OperateCheck_Sys_OperateException;
		}
	}

	public int clearCurGroup(String callIdStr)
	{
		Log.d(THIS_FILE, "clearCurGroup callIdStr = " + callIdStr);
		if(callIdStr == null
				|| callIdStr.equals(MyCall.DEF_CALL_ID_STR))
		{
			return CauseCont.OperateCheck_Sys_OperateException;
		}

		int result = checkFirst();
		if(CauseCont.OperateCheck_Suc != result)
		{
			return result;
		}

		try
		{
			return service.clearCurGroup(callIdStr);
		}
		catch(Exception e)
		{
			e.printStackTrace();
			return CauseCont.OperateCheck_Sys_OperateException;
		}
	}

	public void ring(boolean isRing)
	{
		Log.d(THIS_FILE, "ring isRing = " + isRing);
		if(service == null)
		{
			Log.e(THIS_FILE, "service == null ");
			return;
		}
		try
		{
			service.ring(1,isRing);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}

	public void updateAudioChannel(int callType)
	{
		Log.d(THIS_FILE, "updateAudioChannel callType = " + callType);
		if(service == null)
		{
			Log.e(THIS_FILE, "service == null ");
			return;
		}
		try
		{
			service.updateAudioChannel(callType);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}

	public void requestAudioFocus(boolean isSetSnd)
	{
		Log.d(THIS_FILE, "requestAudioFocus isSetSnd = " + isSetSnd);
		try {
			service.requestAudioFocus(isSetSnd);
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}


//	public void releaseAudioFocus()
//	{
//		Log.d(THIS_FILE, "releaseAudioFocus");
//		try {
//			service.releaseAudioFocus();
//		} catch (RemoteException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//	}
	
	public int opAudioMedia(String callIdStr,int opType)
	{
		Log.d(THIS_FILE, "opAudioMedia callIdStr = " + callIdStr + " opType = " + opType);
		if(callIdStr == null
				|| callIdStr.equals(MyCall.DEF_CALL_ID_STR))
		{
			return CauseCont.OperateCheck_Sys_OperateException;
		}
		
		int result = checkFirst();
		if(CauseCont.OperateCheck_Suc != result)
		{
			return result;
		}

		try
		{
			return service.opAudioMedia(callIdStr, opType);
		}
		catch(Exception e)
		{ 
			e.printStackTrace();
			return CauseCont.OperateCheck_Sys_OperateException;
		}
	}
	
	public int opVideoMedia(String callIdStr,int opType)
	{
		Log.d(THIS_FILE, "opVideoMedia callIdStr = " + callIdStr + " opType = " + opType);
		if(callIdStr == null
				|| callIdStr.equals(MyCall.DEF_CALL_ID_STR))
		{
			return CauseCont.OperateCheck_Sys_OperateException;
		}
		
		int result = checkFirst();
		if(CauseCont.OperateCheck_Suc != result)
		{
			return result;
		}

		try
		{
			return service.opVideoMedia(callIdStr, opType);
		}
		catch(Exception e)
		{ 
			e.printStackTrace();
			return CauseCont.OperateCheck_Sys_OperateException;
		}
	}

//	public int updateCallOptions(int callIdStr, Bundle bundle) {
//		Log.d(THIS_FILE, "updateCallOptions callIdStr = " + callIdStr );
//		if(callIdStr == null
//				|| callIdStr.equals(MyCall.DEF_KEY))
//		{
//			return CauseCont.OperateCheck_Sys_OperateException;
//		}
//
//		if (null != service) {
//			try {
//				return service.updateCallOptions(callIdStr, true,true);
//			} catch (RemoteException e) {
//				e.printStackTrace();
//			}
//		}
//		return -1;
//	}

	public void holdGroupCall(int callId)
	{
		Log.d(THIS_FILE, "holdGroupCall callId = " + callId );
		if(callId < 0
				|| callId > 255)
		{
			return;
		}
//		int callId = 0;
//		if(curCallSession != null)
//		{
//			callId = curCallSession.getCallId();
//		}
		try
		{
			Log.d(THIS_FILE, "doDisconnectCallAction callId is "+ callId);
			service.hold(callId);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}

	public void destoryCall(String callIdStr)
	{
		Log.d(THIS_FILE, "destoryGroupCall");
		if(service == null) 
		{
			Log.e(THIS_FILE, "service == null ");
			return;
		}
		try
		{
			Log.e(THIS_FILE, "destoryCall ");
			service.destoryCall(callIdStr);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
	
	public void clearAllCalls()
	{
		Log.d(THIS_FILE, "clearAllCalls");
		int result = checkFirst();
		if(CauseCont.OperateCheck_Suc != result)
		{
			return;
		}
		try 
		{
//			service.setSpeakerphoneOn( false );
			service.clearAllCalls();
		} catch (RemoteException e) {
			Log.e(THIS_FILE, "Service can't be called to make the call");
		}
	}
	
	public void clearResourceForCallEnd(String callIdStr)
	{
		Log.d(THIS_FILE, "clearResourceForCallEnd callIdStr = " + callIdStr );
		if(callIdStr == null
				|| callIdStr.equals(MyCall.DEF_CALL_ID_STR))
		{
			return;
		}
		
		int result = checkFirst();
		if(CauseCont.OperateCheck_Suc != result)
		{
			return;
		}
		try 
		{
//			service.setSpeakerphoneOn( false );
			service.clearResourceForCallEnd(callIdStr);
		} catch (RemoteException e) {
			Log.e(THIS_FILE, "Service can't be called to make the call");
		}
	}
	
	public boolean isActiveCall()
	{
		Log.d(THIS_FILE, "isActiveNoIncommingCall");
		int result = checkFirst();
		if(CauseCont.OperateCheck_Suc != result)
		{
			return false;
		}
		try 
		{
			return service.isActiveCall();
		} catch (RemoteException e) {
			Log.e(THIS_FILE, "Service can't be called to make the call");
			return true;
		}
	}
	
	public boolean isIncommingCall()
	{
		Log.d(THIS_FILE, "isIncommingCall");
		int result = checkFirst();
		if(CauseCont.OperateCheck_Suc != result)
		{
			return false;
		}
		try 
		{
			return service.isIncommingCall();
		} catch (RemoteException e) {
			Log.e(THIS_FILE, "Service can't be called to make the call");
			return false;
		}
	}

//	protected void sendSysMsg(String msgStr) 
//	{
//		Log.d(THIS_FILE, "sendSysMsg msgStr is " + msgStr);
//		if (service == null) {
//			Log.e(THIS_FILE, "service is null");
//			return;
//		}
//		try 
//		{
//			service.sendSystemMessage(msgStr);
//		} catch (RemoteException e) {
//			Log.e(THIS_FILE, "Service can't be called to make the call");
//		}
//	}
	
//	private void setSpeakerphoneOn(int callType, boolean isAnswer) throws Exception
//	{
//		MediaState ms = service.getCurrentMediaState();		
//
//		if(!ms.canBluetoothSco)
//		{
//			if(SipCallSession.Call_Group == callType)
//			{
//				service.setSpeakerphoneOn(true);//
//			}
//			else if(SipCallSession.Call_Privacy == callType)
//			{
//				service.setSpeakerphoneOn( (null != config) ? config.isPrivateSpeakerOn() : false );
//			}
//
//			Log.e(THIS_FILE, "setSpeakerphoneOn() : callType=" + callType + ",isAnswer=" + isAnswer);
//		}
//		else if(ms.canBluetoothSco && !ms.isBluetoothScoOn)
//		{
//			service.setBluetoothOn(true);
//		}
//	}
	
//	private void setSpeakerphoneOn(int callType) throws Exception
//	{
////		MediaState ms = service.getCurrentMediaState();		
//
////		if(!ms.canBluetoothSco)
////		{
//			if(CallAttr.CallType_Group == callType)
//			{
////				service.setSpeakerphoneOn(true);
//			}
//			else if(CallAttr.CallType_Webrtc_Single == callType)
//			{
////				boolean isTrue = isPrivateSpeakerOn();
////				Log.e(THIS_FILE, "setSpeakerphoneOn isTrue=" + isTrue);
////				service.setSpeakerphoneOn(true);
//			}
//
//			Log.e(THIS_FILE, "setSpeakerphoneOn() : callType=" + callType);
////		}
////		else if(ms.canBluetoothSco && !ms.isBluetoothScoOn)
////		{
////			service.setBluetoothOn(true);
////		}
//	}
	
//	public void setNoSnd() throws Exception
//	{
//		if(Product.getProductType() == ProductConst.ProductType_NAPP)
//		{
//			return;
//		}
//		Log.e(THIS_FILE, "setNoSnd");
//		service.setNoSnd();
//	}
//	
//	public void setSnd(boolean isMust) throws Exception
//	{
//		if(Product.getProductType() == ProductConst.ProductType_NAPP)
//		{
//			return;
//		}
//		Log.e(THIS_FILE, "setSnd isMust =" + isMust);
//		service.setSnd();
//	}
	
	public void screenAngle(String callIdStr,int angle)
	{
		Log.d(THIS_FILE, "screenAngle callIdStr =" + callIdStr + " angle = " + angle);
//		try {
//			service.screenAngle(callId,angle);
//		} catch (RemoteException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
	}

	public String showCallInfosDialog( int callId ){
		
		Log.d(THIS_FILE, "showCallInfosDialog callId = " + callId );
		String info = "";
		if(callId < 0
				|| callId > 255)
		{
			return info;
		}
		
		if( null != service )
    	{
    		try {
				info = service.showCallInfosDialog( callId );
			} catch (RemoteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    	}
		
		return info;
	}
	
	public String getLocalNatType(){
		String natType="";
		try {
			natType = service.getLocalNatType();
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return natType;
	}
	
	public void playWaveFile(final String filePath, final String callIdStr, final int way){
//		try {
//			service.playWaveFile(filePath, callIdStr, way);
//		} catch (RemoteException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
	}
	
	public void sendSubscribe(String uri){
		try {
			service.sendSubscribe(uri);
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void onVol(int type)
	{
		Log.d(THIS_FILE, "onVol type = " + type);
		try {
			service.onVol(type);
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void setSpeakerphoneOn(boolean on)
	{
		try {
			service.setSpeakerphoneOn(on);
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public void muteCall(String callIdStr,boolean isOn)
	{
		Log.d(THIS_FILE, "muteCall callIdStr = " + callIdStr + " isOn = " + isOn);
		if(callIdStr == null
				|| callIdStr.equals(MyCall.DEF_CALL_ID_STR))
		{
			return;
		}
		try
		{
//			service.muteCall(callId, isOn);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
	
//	public void playWaveFile(final String filePath, final int callId, final int way){
//		try {
//			service.playWaveFile(filePath, callId, way);
//		} catch (RemoteException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//	}

	public boolean isVidOk(String callIdStr) {
		try {
			return PjsuaService.isVidOk(callIdStr);
		}
		catch (Exception e)
		{
			return false;
		}

	}
	public void startPreView(String callIdStr,Surface surface) {
		PjsuaService.opStartPreView(callIdStr,surface);
	}
	public void stopPreView(String callIdStr) {
		PjsuaService.opStopPreView(callIdStr);
	}

	public void setRemoteView(String callIdStr,Surface surface){
		try {
			PjsuaService.opSetRemoteSurfaceView(callIdStr,surface);
		}catch (Exception e){
			e.printStackTrace();
		}
	}

	public void setCaptureOrient(int orient){
		try {
			PjsuaService.opSetCaptureOrient(orient);
		}catch (Exception e){
			e.printStackTrace();
		}
	}
}
